/*
The MIT License (MIT)
Copyright (c) 2013 Dalvik Boss dalvikboss@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package sidl.generator.xcode.helperclass;

import sidl.Clazz;
import sidl.Field;
import sidl.Type;
import sidl.generator.GeneratorContext;
import sidl.generator.xcode.XCodeGenerator;

public class XCodeByteBufferGenerator extends XCodeGenerator {

	public XCodeByteBufferGenerator(GeneratorContext context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void doGenerateXCode() throws Throwable {
		generateByteBuffer();

	}
	
	private void generateByteBuffer() {
		println("@interface helper_%s_%s_ByteBuffer : NSObject", doc.cPackageName(), doc.mainInf().name);
		println("{");
	    println("    struct {");
	    println("        char data[%s_%s_PACKET_MAX];",doc.cPackageName().toUpperCase(), doc.mainInf().name.toUpperCase());
	    println("        int pos;");
	    println("        int limit;");
	    println("    }buffer;");
		println("}");;
		println("-(helper_%s_%s_ByteBuffer*) init;",doc.cPackageName(), doc.mainInf().name);
		println("-(void) flip;");
		println("-(void) reset;");
		println("-(void) net_send: (int)fd;");
		println("-(void) net_recv: (int)fd;");

		declarePuts();
		declareGets();



		println("@end");

		println("@implementation helper_%s_%s_ByteBuffer : NSObject", doc.cPackageName(), doc.mainInf().name);
		implement_init();
		implement_flip();
		implement_reset();

		implement_net_send();
		implement_net_recv();

		for(Clazz clz: doc.clazzes) {
			implement_put_clz_array(clz);
			implement_put_clz(clz);
			implement_get_clz_array(clz);
			implement_get_clz(clz);

			
		}
		implement_put_String();
		implement_put_String_array();
		implement_get_String();
		implement_get_String_array();
		
		implement_put_buffer();
		implement_get_buffer();

		implement_put_int();
		implement_put_int_at();
		implement_put_int_array();
		implement_get_int();
		implement_get_int_at();

		implement_get_int_array();

		implement_put_short();
		implement_put_short_array();
		implement_get_short();
		implement_get_short_array();
		
		
		implement_put_float();
		implement_put_float_array();
		implement_get_float();
		implement_get_float_array();
		
		
		
		implement_put_double();
		implement_put_double_array();
		implement_get_double();
		implement_get_double_array();
		
		
		implement_put_sidl_long();
		implement_put_sidl_long_array();
		implement_get_sidl_long();
		implement_get_sidl_long_array();
		
		implement_put_sidl_bool();
		implement_put_sidl_bool_array();
		implement_get_sidl_bool();
		implement_get_sidl_bool_array();
		
		implement_put_sidl_char();
		implement_put_sidl_char_array();
		implement_get_sidl_char();
		implement_get_sidl_char_array();
		
		
		implement_put_sidl_byte();
		implement_put_sidl_byte_array();
		implement_get_sidl_byte();
		implement_get_sidl_byte_array();
		
		

		println("@end");
		
	}

	private void declarePuts() {
		for(Clazz clz: doc.clazzes) {
			println("-(void) put_%s: (%s_%s*) value;", clz.name, doc.cPackageName(), clz.name);
			println("-(void) put_%s_array: (NSArray*) array;", clz.name);
			
		}
		for(String t: Type.prims) {
			println("-(void) put_%s: (%s) value;", Type.asObjcName(t), Type.asObjcName(t));
			println("-(void) put_%s_array: (NSArray*) array;", Type.asObjcName(t));
		}
		println("-(void) put_String: (NSString*) value;");
		println("-(void) put_String_array: (NSArray*) array;");
		println("-(void) put_buffer: (const char*) data : (int) off : (int) len;");	
		println("-(void) put_int_at: (int) value : (int) pos;");		

	}

	private void declareGets() {
		for(Clazz clz: doc.clazzes) {
			println("-(%s_%s*) get_%s;", doc.cPackageName(), clz.name, clz.name);
			println("-(NSArray*) get_%s_array;", clz.name);
			
		}
		for(String t: Type.prims) {
			println("-(%s) get_%s;", Type.asObjcName(t), Type.asObjcName(t));
			println("-(NSArray*) get_%s_array;", Type.asObjcName(t));

		}
		
		println("-(NSString*) get_String;");
		println("-(NSArray*) get_String_array;");
		println("-(void) get_buffer: (const char*) data : (int) off : (int) len;");		
		println("-(int) get_int_at:  (int) pos;");		

	
	}
	
	private void implement_init() {
		println("-(helper_%s_%s_ByteBuffer*) init",doc.cPackageName(), doc.mainInf().name);
		println("{");
		println("    self = [super init];");
	    println("    memset(buffer.data,0,%s_%s_PACKET_MAX);",doc.cPackageName().toUpperCase(), doc.mainInf().name.toUpperCase());
	    println("    return self;");
		println("}");
	}
	
	private void implement_flip() {
		println("-(void) flip");
		println("{");
		println("    buffer.limit = buffer.pos;");
		println("    buffer.pos = 0;");
		println("}");
	}
	
	private void implement_reset() {
		println("-(void) reset");
		println("{");
		println("    buffer.limit = 0;");
		println("    buffer.pos = 0;");
		println("}");
	}
	
	
	private void implement_net_send() {
		println("-(void) net_send: (int)fd");
		println("{");
	    println("    int total = buffer.limit;");
	    println("    [self put_int_at:total-4:0];");
	    println("    int to_send = total;");
	    println("    while(to_send > 0) {");
	    println("        ssize_t r = send(fd, &buffer.data[total-to_send], to_send, 0);");
	    println("        if(r<=0) {");
	    println("            break;");
	    println("        }");
	    println("        to_send -= r;");
	    println("    }");
	    println("    if(to_send > 0) {");
	    println("        @throw [[%s_%s_SidlExecption alloc] initWith:MSG_SEND_ERROR];", doc.cPackageName(), doc.mainInf().name);
	    println("    }");

	    
		println("}");
	}
	
	private void implement_net_recv() {
		println("-(void) net_recv: (int)fd ");
		println("{");
	    println("    char intBuf[4];");
	    println("    int to_read = 4;");
	    println("    while(to_read > 0) {");
	    println("        ssize_t r = recv(fd, &intBuf[4-to_read], to_read, 0);");
	    println("        if(r<=0) {");
	    println("            break;");
	    println("        }");
	    println("        to_read -=r;");
	    println("    }");
	    println("    if(to_read>0) {");
	    println("        @throw [[%s_%s_SidlExecption alloc] initWith:MSG_RECV_ERROR];", doc.cPackageName(), doc.mainInf().name);
	    println("    }");
	    println("    [self put_buffer:intBuf :0 :4];");
	    println("    [self flip];");
	    println("    int packetLen = [self get_int];");
	    println("    [self reset];");
	    println("    to_read = packetLen;");
	    println("    while(to_read > 0) {");
	    println("        char buf[1024];");
	    println("        ssize_t r = recv(fd, buf, to_read>1024?1024:to_read, 0);");
	    println("        if(r<=0) {");
	    println("            break;");
	    println("        }");
	    println("        to_read -=r;");
	    println("        [self put_buffer:buf :0 :(int)r];");
	    println("    }");
	    println("    if(to_read>0) {");
	    println("        @throw [[%s_%s_SidlExecption alloc] initWith:MSG_RECV_ERROR];", doc.cPackageName(), doc.mainInf().name);
	    println("    }");

	    
		println("}");
	}
	
	
	//		println("-(void) net_send: (int)fd;");
	//println("-(void) net_recv: (int)fd;");
	
	

	private void implement_put_clz(Clazz clz) {
		println("-(void) put_%s: (%s_%s*) value", clz.name, doc.cPackageName(), clz.name);
		println("{");
		println("    if(!value) ");
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
		println("        [self put_int:1];");
		for(Field f: clz.fields) {
			println("        [self put_%s%s:[value %s]];", Type.asObjcName(f.type.name), (f.type.isArray?"_array":""), f.name);
		}
		println("    }");
		println("}");		
	}

	private void implement_put_clz_array(Clazz clz) {
		println("-(void) put_%s_array: (NSArray*) array", clz.name);
		println("{");
		println("    if(!array) ");
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
		println("        [self put_int:(int)[array count]];");
		println("        for(int i = 0; i < [array count]; i++)");
		println("        {");
		println("            [self put_%s:[array objectAtIndex: i]];", clz.name);
		println("        }");
		println("    }");
		println("}");		
	}

	

	private void implement_get_clz(Clazz clz) {
		println("-(%s_%s*) get_%s", doc.cPackageName(), clz.name, clz.name);
		println("{");
	    println("    int flag = [self get_int];");
	    println("    if(flag==-1) {");
	    println("        return NULL;");
	    println("    }");
	    println("    %s_%s *result = [[%s_%s alloc] init];",doc.cPackageName(), clz.name,doc.cPackageName(), clz.name);
	    for(Field f: clz.fields) {
	    	if(f.type.isArray) {
	    		println("    [result %s:[self get_%s_array]];", f.asObjcSetter(), Type.asObjcName(f.type.name));
	    	} else {
	    		println("    [result %s:[self get_%s]];", f.asObjcSetter(), Type.asObjcName(f.type.name));

	    	}
	    }
	    println("    return result;");
		println("}");		
	}

	private void implement_get_clz_array(Clazz clz) {
		println("-(NSArray*) get_%s_array", clz.name);
		println("{");
		println("    int len = [self get_int];");
		println("    if(len==-1)");
		println("    {");
		println("        return NULL;");
		println("    }");
		println("    NSMutableArray *array = [[NSMutableArray alloc] init];");
	    println("    for(int i = 0; i < len; i++) {");
	    println("        [array addObject:[self get_%s]];", clz.name);
	    println("    }");
	    
		println("    return array;");
		println("}");		
	}

	
	
	private void implement_put_String() {
		println("-(void) put_String: (NSString*) value");
		println("{");
		println("    if(!value) ");
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
        println("        int len = (int)[value lengthOfBytesUsingEncoding:NSUTF8StringEncoding];");
        println("        const char* data = [value UTF8String];");
        println("        if(data && (len >=0)) {");
        println("            [self put_int:len];");
        println("            [self put_buffer:data :0 :len];");
        println("        } else {");
        println("            [self put_int:-1];");
        println("        ");
        println("        }");
		println("    }");		
		println("}");		
	}

	private void implement_put_String_array() {
		Clazz clz = new Clazz();
		clz.name = "String";
		implement_put_clz_array(clz);
	}
	
	private void implement_get_String() {
		println("-(NSString*) get_String");
		println("{");
		
	    println("    int len = [self get_int];");
	    println("    if(len==-1) {");
	    println("        return NULL;");
	    println("    }");
	    println("    char *data = (char*)malloc(len+1);");
	    println("    data[len] = 0;");
	    println("    [self get_buffer:data:0 :len];");
	    println("    NSString *result = [NSString stringWithUTF8String:data];");
	    println("    free(data);");
	    println("    return result;");
	    
		println("}");		
	}

	private void implement_get_String_array() {
		Clazz clz = new Clazz();
		clz.name = "String";
		implement_get_clz_array(clz);
	}
	
	
	private void implement_put_buffer() {
		println("-(void) put_buffer: (const char*) data : (int) off : (int) len");
		println("{");
		println("    if(len<=0)");
		println("    {");
		println("        return;");
		println("    }");
		println("    ");
		println("    if(buffer.pos + len > %s_%s_PACKET_MAX)", doc.cPackageName().toUpperCase(), doc.mainInf().name.toUpperCase());
		println("    {");
		println("        @throw [[%s_%s_SidlExecption alloc] initWith:MSG_BUFFER_FULL];", doc.cPackageName(), doc.mainInf().name);
		println("    }");
		println("    memcpy(&buffer.data[buffer.pos], &data[off], len);");
		println("    buffer.pos += len;");
		println("}");
		
	}

	private void implement_get_buffer() {
		println("-(void) get_buffer: (const char*) data : (int) off : (int) len");
		println("{");
		println("    if(len<=0)");
		println("    {");
		println("        return;");
		println("    }");
		println("    ");
		println("    if(buffer.pos + len > buffer.limit)");
		println("    {");
		println("        @throw [[%s_%s_SidlExecption alloc] initWith:MSG_BUFFER_EOF];",doc.cPackageName(), doc.mainInf().name);
		println("    }");
		println("    memcpy((void*)&data[off], &buffer.data[buffer.pos], len);");
		println("    buffer.pos += len;");
		println("}");
		
	}

	




	private void implement_put_int() {

		println("-(void) put_int: (int) value");
		println("{");
	    println("    char buf[4];");
	    println("    buf[3] = (char)(value & 0x000000ff);");
	    println("    buf[2] = (char)((value >> 8)  & 0x000000ff);");
	    println("    buf[1] = (char)((value >> 16) & 0x000000ff);");
	    println("    buf[0] = (char)((value >> 24) & 0x000000ff);");
	    println("    [self put_buffer:buf :0 :4];");
	    
		println("}");
		

	}
	

	private void implement_put_int_at() {

		println("-(void) put_int_at: (int) value : (int) pos");
		println("{");
		println("    char buf[4];");
		println("    buf[3] = (char)(value & 0x000000ff);");
		println("    buf[2] = (char)((value >> 8)  & 0x000000ff);");
		println("    buf[1] = (char)((value >> 16) & 0x000000ff);");
		println("    buf[0] = (char)((value >> 24) & 0x000000ff);");
		println("   ");
		println("    if(pos + 4 > %s_%s_PACKET_MAX)", doc.cPackageName().toUpperCase(), doc.mainInf().name.toUpperCase());
		println("    {");
		println("        @throw [[%s_%s_SidlExecption alloc] initWith:MSG_BUFFER_FULL];", doc.cPackageName(), doc.mainInf().name);
		println("    }");
		println("    memcpy(&buffer.data[pos], buf, 4);");
		println("}");
		
		

	}
	


	private void implement_put_int_array() {

		println("-(void) put_int_array: (NSArray*) array");
		println("{");
		println("    if(!array)"); 
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
		println("        [self put_int:(int)[array count]];");
		println("        for(int i = 0; i < [array count]; i++)");
		println("        {");
		println("            [self put_int:[[array objectAtIndex:i] intValue]];");
		println("        }");
		println("    }");
		println("}");
		
		
	}
	
	private void implement_get_int() {

		println("-(int) get_int");
		println("{");

	    println("    char buf[4];");
	    println("    [self get_buffer:buf :0 :4];");
	    println("    int v =");
	    println("        ((buf[3] << 0)  & 0x000000ff) |");
	    println("        ((buf[2] << 8)  & 0x0000ff00) |");
	    println("        ((buf[1] << 16) & 0x00ff0000) |");
	    println("        ((buf[0] << 24) & 0xff000000);");
	    println("    return v;");
	    
	    
		println("}");
		

	}

	private void implement_get_int_at() {


		println("-(int) get_int_at: (int) pos");
		println("{");
		println("    char buf[4];");
		println("    ");
		println("    if(pos + 4 > %s_%s_PACKET_MAX)", doc.cPackageName().toUpperCase(), doc.mainInf().name.toUpperCase());
		println("    {");
		println("        @throw [[%s_%s_SidlExecption alloc] initWith:MSG_BUFFER_EOF];", doc.cPackageName(), doc.mainInf().name);
		println("    }");
		println("    memcpy(buf, &buffer.data[pos], 4);");
		println("  ");  
		println("    int v =");
		println("        ((buf[3] << 0)  & 0x000000ff) |");
		println("        ((buf[2] << 8)  & 0x0000ff00) |");
		println("        ((buf[1] << 16) & 0x00ff0000) |");
		println("        ((buf[0] << 24) & 0xff000000);");
		println("    return v;");
		println("}");
		
		

	}

	

	private void implement_get_int_array() {

		println("-(NSArray*) get_int_array");
		println("{");
	    println("    int len = [self get_int];");
	    println("    if(len==-1)");
	    println("    {");
	    println("        return NULL;");
	    println("    }");
	    println("    NSMutableArray *array = [[NSMutableArray alloc] init];");
	    println("    for(int i = 0; i < len; i++) {");
	    println("        NSNumber *num = [NSNumber numberWithInt:[self get_int]];");
	    println("        [array addObject:num];");
	    println("    }");
	    println("    return array;");
	    
		println("}");
		
	}
	
	
	
	private void implement_put_short() {

		println("-(void) put_short: (short) value");
		println("{");
	    println("    char buf[2];");
	    println("    buf[1] = (char)(value & 0x000000ff);");
	    println("    buf[0] = (char)((value >> 8)  & 0x000000ff);");
	    println("    [self put_buffer:buf :0 :2];");
	    
		println("}");
		

	}


	private void implement_put_short_array() {

		println("-(void) put_short_array: (NSArray*) array");
		println("{");
		println("    if(!array)"); 
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
		println("        [self put_int:(int)[array count]];");
		println("        for(int i = 0; i < [array count]; i++)");
		println("        {");
		println("            [self put_short:[[array objectAtIndex:i] shortValue]];");
		println("        }");
		println("    }");
		println("}");
		
		
	}
	
	
	private void implement_get_short() {

		println("-(short) get_short");
		println("{");

	    println("    char buf[2];");
	    println("    [self get_buffer:buf :0 :2];");
	    println("    short v =");
	    println("        ((buf[1] << 0)  & 0x00ff) |");
	    println("        ((buf[0] << 8)  & 0xff00);");
	    println("    return v;");
	    
	    
		println("}");
		

	}


	private void implement_get_short_array() {

		println("-(NSArray*) get_short_array");
		println("{");
	    println("    int len = [self get_int];");
	    println("    if(len==-1)");
	    println("    {");
	    println("        return NULL;");
	    println("    }");
	    println("    NSMutableArray *array = [[NSMutableArray alloc] init];");
	    println("    for(int i = 0; i < len; i++) {");
	    println("        NSNumber *num = [NSNumber numberWithShort:[self get_short]];");
	    println("        [array addObject:num];");
	    println("    }");
	    println("    return array;");
	    
		println("}");
		
	}
	
	
	
	private void implement_put_float() {

		println("-(void) put_float: (float) value");
		println("{");
	    println("    [self put_buffer:(const char*)&value :0 :sizeof(value)];");
	    
		println("}");
		

	}


	private void implement_put_float_array() {

		println("-(void) put_float_array: (NSArray*) array");
		println("{");
		println("    if(!array)"); 
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
		println("        [self put_int:(int)[array count]];");
		println("        for(int i = 0; i < [array count]; i++)");
		println("        {");
		println("            [self put_float:[[array objectAtIndex:i] floatValue]];");
		println("        }");
		println("    }");
		println("}");
		
		
	}
	
	
	private void implement_get_float() {

		println("-(float) get_float");
		println("{");

	    println("    float result;");
	    println("    [self get_buffer:(char*)&result :0 :sizeof(float)];");
	    println("    return result;");
	    
	    
		println("}");
		

	}


	private void implement_get_float_array() {

		println("-(NSArray*) get_float_array");
		println("{");
	    println("    int len = [self get_int];");
	    println("    if(len==-1)");
	    println("    {");
	    println("        return NULL;");
	    println("    }");
	    println("    NSMutableArray *array = [[NSMutableArray alloc] init];");
	    println("    for(int i = 0; i < len; i++) {");
	    println("        NSNumber *num = [NSNumber numberWithFloat:[self get_float]];");
	    println("        [array addObject:num];");
	    println("    }");
	    println("    return array;");
	    
		println("}");
		
	}
	
	
	
	private void implement_put_double() {

		println("-(void) put_double: (double) value");
		println("{");
	    println("    [self put_buffer:(const char*)&value :0 :sizeof(value)];");
	    
		println("}");
		

	}


	private void implement_put_double_array() {

		println("-(void) put_double_array: (NSArray*) array");
		println("{");
		println("    if(!array)"); 
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
		println("        [self put_int:(int)[array count]];");
		println("        for(int i = 0; i < [array count]; i++)");
		println("        {");
		println("            [self put_double:[[array objectAtIndex:i] doubleValue]];");
		println("        }");
		println("    }");
		println("}");
		
		
	}
	
	
	private void implement_get_double() {

		println("-(double) get_double");
		println("{");

	    println("    double result;");
	    println("    [self get_buffer:(char*)&result :0 :sizeof(double)];");
	    println("    return result;");
	    
	    
		println("}");
		

	}


	private void implement_get_double_array() {

		println("-(NSArray*) get_double_array");
		println("{");
	    println("    int len = [self get_int];");
	    println("    if(len==-1)");
	    println("    {");
	    println("        return NULL;");
	    println("    }");
	    println("    NSMutableArray *array = [[NSMutableArray alloc] init];");
	    println("    for(int i = 0; i < len; i++) {");
	    println("        NSNumber *num = [NSNumber numberWithDouble:[self get_double]];");
	    println("        [array addObject:num];");
	    println("    }");
	    println("    return array;");
	    
		println("}");
		
	}
	
	
	
	

	private void implement_put_sidl_long() {

		println("-(void) put_sidl_long: (sidl_long) value");
		println("{");
	    println("    char buf[8];");
	    println("    buf[7] = (char)((value >>  0)  & 0x00000000000000ffLL);");
	    println("    buf[6] = (char)((value >>  8)  & 0x00000000000000ffLL);");
	    println("    buf[5] = (char)((value >> 16)  & 0x00000000000000ffLL);");
	    println("    buf[4] = (char)((value >> 24)  & 0x00000000000000ffLL);");
	    println("    buf[3] = (char)((value >> 32)  & 0x00000000000000ffLL);");
	    println("    buf[2] = (char)((value >> 40)  & 0x00000000000000ffLL);");
	    println("    buf[1] = (char)((value >> 48)  & 0x00000000000000ffLL);");
	    println("    buf[0] = (char)((value >> 56)  & 0x00000000000000ffLL);");
	    println("    [self put_buffer:buf :0 :8];");
	    
		println("}");
				
	}

	

	private void implement_put_sidl_long_array() {
		println("-(void) put_sidl_long_array: (NSArray*) array");
		println("{");
		println("    if(!array)"); 
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
		println("        [self put_int:(int)[array count]];");
		println("        for(int i = 0; i < [array count]; i++)");
		println("        {");
		println("            [self put_sidl_long:[[array objectAtIndex:i] longLongValue]];");
		println("        }");
		println("    }");
		println("}");
		

	}

	
	private void implement_get_sidl_long() {

		println("-(sidl_long) get_sidl_long");
		println("{");

	    println("    char buf[8];");
	    println("    [self get_buffer:buf :0 :8];");
	    println("    sidl_long v =");
	    println("        (((sidl_long)buf[7] <<  0)  & 0x00000000000000ffLL) |");
	    println("        (((sidl_long)buf[6] <<  8)  & 0x000000000000ff00LL) |");
	    println("        (((sidl_long)buf[5] << 16)  & 0x0000000000ff0000LL) |");
	    println("        (((sidl_long)buf[4] << 24)  & 0x00000000ff000000LL) |");
	    println("        (((sidl_long)buf[3] << 32)  & 0x000000ff00000000LL) |");
	    println("        (((sidl_long)buf[2] << 40)  & 0x0000ff0000000000LL) |");
	    println("        (((sidl_long)buf[1] << 48)  & 0x00ff000000000000LL) |");
	    println("        (((sidl_long)buf[0] << 56)  & 0xff00000000000000LL);");
	    println("    return v;");
	    
	    
		println("}");
		

	}


	private void implement_get_sidl_long_array() {

		println("-(NSArray*) get_sidl_long_array");
		println("{");
	    println("    int len = [self get_int];");
	    println("    if(len==-1)");
	    println("    {");
	    println("        return NULL;");
	    println("    }");
	    println("    NSMutableArray *array = [[NSMutableArray alloc] init];");
	    println("    for(int i = 0; i < len; i++) {");
	    println("        NSNumber *num = [NSNumber numberWithLongLong:[self get_sidl_long]];");
	    println("        [array addObject:num];");
	    println("    }");
	    println("    return array;");
	    
		println("}");
		
	}
	
	
	private void implement_put_sidl_bool() {

		println("-(void) put_sidl_bool: (sidl_bool) value");
		println("{");
	    println("    char buf[4];");
	    println("    buf[3] = (char)(value & 0x000000ff);");
	    println("    buf[2] = (char)((value >> 8)  & 0x000000ff);");
	    println("    buf[1] = (char)((value >> 16) & 0x000000ff);");
	    println("    buf[0] = (char)((value >> 24) & 0x000000ff);");
	    println("    [self put_buffer:buf :0 :4];");
	    
		println("}");
				
	}

	

	private void implement_put_sidl_bool_array() {
		println("-(void) put_sidl_bool_array: (NSArray*) array");
		println("{");
		println("    if(!array)"); 
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
		println("        [self put_int:(int)[array count]];");
		println("        for(int i = 0; i < [array count]; i++)");
		println("        {");
		println("            [self put_sidl_bool:[[array objectAtIndex:i] intValue]];");
		println("        }");
		println("    }");
		println("}");
		

	}

	

	private void implement_get_sidl_bool() {

		println("-(sidl_bool) get_sidl_bool");
		println("{");

	    println("    char buf[4];");
	    println("    [self get_buffer:buf :0 :4];");
	    println("    sidl_bool v =");
	    println("        ((buf[3] << 0)  & 0x000000ff) |");
	    println("        ((buf[2] << 8)  & 0x0000ff00) |");
	    println("        ((buf[1] << 16) & 0x00ff0000) |");
	    println("        ((buf[0] << 24) & 0xff000000);");
	    println("    return v;");
	    
	    
		println("}");
		

	}


	private void implement_get_sidl_bool_array() {

		println("-(NSArray*) get_sidl_bool_array");
		println("{");
	    println("    int len = [self get_int];");
	    println("    if(len==-1)");
	    println("    {");
	    println("        return NULL;");
	    println("    }");
	    println("    NSMutableArray *array = [[NSMutableArray alloc] init];");
	    println("    for(int i = 0; i < len; i++) {");
	    println("        NSNumber *num = [NSNumber numberWithInt:[self get_int]];");
	    println("        [array addObject:num];");
	    println("    }");
	    println("    return array;");
	    
		println("}");
		
	}
	
	
	
	private void implement_put_sidl_char() {

		println("-(void) put_sidl_char: (sidl_char) value");
		println("{");
	    println("    [self put_buffer:&value :0 :1];");
	    
		println("}");
				
	}

	

	private void implement_put_sidl_char_array() {
		println("-(void) put_sidl_char_array: (NSArray*) array");
		println("{");
		println("    if(!array)"); 
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
		println("        [self put_int:(int)[array count]];");
		println("        const sidl_char *buf = [(NSData*) [array objectAtIndex:0] bytes];");
	    println("        [self put_buffer:buf :0 :(int)[array count]];");
		println("    }");
		println("}");
		

	}
	

	private void implement_get_sidl_char() {

		println("-(sidl_char) get_sidl_char");
		println("{");
	    println("    char v;");
	    println("    [self get_buffer:&v :0 :1];");
	    println("    return v;"); 
		println("}");
		

	}


	private void implement_get_sidl_char_array() {

		println("-(NSArray*) get_sidl_char_array");
		println("{");
	    println("    int len = [self get_int];");
	    println("    if(len==-1)");
	    println("    {");
	    println("        return NULL;");
	    println("    }");
	    println("    NSMutableArray *array = [[NSMutableArray alloc] init];");
	    println("    for(int i = 0; i < len; i++) {");
	    println("        NSNumber *num = [NSNumber numberWithChar:[self get_sidl_char]];");
	    println("        [array addObject:num];");
	    println("    }");
	    println("    return array;");
	    
		println("}");
		
	}
	
	
	private void implement_put_sidl_byte() {

		println("-(void) put_sidl_byte: (sidl_byte) value");
		println("{");
	    println("    [self put_buffer:&value :0 :1];");
	    
		println("}");
				
	}

	

	private void implement_put_sidl_byte_array() {
		println("-(void) put_sidl_byte_array: (NSArray*) array");
		println("{");
		println("    if(!array)"); 
		println("    {");
		println("        [self put_int:-1];");
		println("    } else");
		println("    {");
		println("        [self put_int:(int)[array count]];");
		println("        const sidl_byte *buf = [(NSData*) [array objectAtIndex:0] bytes];");
	    println("        [self put_buffer:buf :0 :(int)[array count]];");
		println("    }");
		println("}");
		

	}

	
	private void implement_get_sidl_byte() {

		println("-(sidl_byte) get_sidl_byte");
		println("{");
	    println("    sidl_byte v;");
	    println("    [self get_buffer:&v :0 :1];");
	    println("    return v;"); 
		println("}");
		

	}


	private void implement_get_sidl_byte_array() {

		println("-(NSArray*) get_sidl_byte_array");
		println("{");
	    println("    int len = [self get_int];");
	    println("    if(len==-1)");
	    println("    {");
	    println("        return NULL;");
	    println("    }");
	    println("    NSMutableArray *array = [[NSMutableArray alloc] init];");
	    println("    for(int i = 0; i < len; i++) {");
	    println("        NSNumber *num = [NSNumber numberWithChar:[self get_sidl_byte]];");
	    println("        [array addObject:num];");
	    println("    }");
	    println("    return array;");
	    
		println("}");
		
	}
	
	
}
